#include <iostream>
#include <string>
#include <math.h>
#include <fstream>
#include <algorithm>
#include <stdio.h>
#include <boost/filesystem/path.hpp>
#include <boost/program_options.hpp>
#include "get_arg.h"



// link with -lboost_filesystem-gcc -lboost_program_options-gcc
// program_options_helper.cpp
//-lboost_filesystem-gcc-d
//-L/usr/local/lib





// my functions
#include <print_error.h>
#include <program_options_helper.h>
#include <stlhelper.h>
#define DEBUG_LEVEL 6
#include <debug_func.h>

using std::string;
using std::cerr;
using std::string;
using std::ofstream;
using std::ifstream;
using std::cerr;
using std::cout;
using std::vector;
using std::max;
using std::sort;
using namespace program_options_helper;
namespace po = boost::program_options_lg;


//_______________________________________________________________________________________

//		process_command_line_options

//				from command line
//				Created [9/13/2001]

//_______________________________________________________________________________________
bool process_command_line_options(int argc, char* argv[], t_program_args& args)
{

	//
	// checked mandatory arguments
	//
	po::options_description mandatory_args("Mandatory Arguments");
	mandatory_args.add_options()
	("sequences,s", po::value<string>(&args.file_seq)->set_name("FILE"),
						"FILE with sequences in FASTA format.\n"
						"Sequences need not be in order.");


	string pair_indices_str;
	args.optional_args.add_options()
	("i_name,i", 	po::value<string>(&args.name1)
							->set_name("ID"),
						"Name of 1st sequence to be aligned.")
	("j_name,j", 	po::value<string>(&args.name2)
							->set_name("ID"),
						"Name of 2nd sequence to be aligned.")
	("pairs,p",  	po::value<string>(&pair_indices_str)
							->set_name("INDICES"),
						"Indices in the alignment data file of the sequence "
						"pairs to be aligned (starting from the 0th),\n"
						"where e.g. INDICES = \"1,3,9,11-13\".\n")
	("regex,r",  	po::value<string>(&args.regex)->set_name("REGEX")
							->default_value("(\\S+)"),
						"Regular expression for extracting the sequence identifier.\n"
						"E.g \"[^|]+\\|([^|]+)\\|\"\n"
						"Defaults to first non-whitespace characters on the "
						"accession line")
	("cdna,c",	 	po::bool_switch(&args.cdna),
					   "Sequences are cDNA rather than protein.")
	("kaks,k",	 	po::bool_switch(&args.kaks),
					   "Alignment data includes kaks results.")
	("wrap,w",	 	po::bool_switch(&args.wrap),
					   "Line wrap sequences every 60 letters.")
	("#comment,#",	po::value<string>(&args.comment_letters)
							->set_name("LETTERS")
							->default_value("#"),
						"Use one of these letters to begin a "
						"commented line.");


	args.add_std_options();
	po::options_description all_args("");
	all_args.add(mandatory_args).add(args.optional_args);

	// parse command line
	po::variables_map vm;
	po::store(po::command_line_parser(argc, argv).options(all_args).run(), vm);
	po::notify(vm);

	if (vm.count("version"))
	{
		print_version(cerr, *argv, 
			"1.2\n"
			"\tHistory: \n\n"
			"\tv 1.0\1"
			"Initial version\n"
			"\tv 1.1\1"
			"04-01-2006\1"
			"For Andreas: Hash start comment lines. Fix bugs in handling input. Upgrade to common code "
			"for sequence pair identifiers\n"
			"\tv 1.2\1"
			"27-03-2006\1"
			"Comments can begin with user-defined letters. Defaults to hash '#'\n"
			);
		return false;
	}
	if (vm.count("help"))
	{
		string exe_description =
					"Aligns two sequences using previously calculated alignment data.\n"
					"Alignment data is supplied via STDIN.\n"
					"Aligned sequences in FASTA format are printed to STDOUT in the order "
					"they are specified, including duplicates.\n"
					"If neither --i_name or --pairs is specified, then all pairs of "
					"sequences with alignment data will be printed out in aligned format.\n";
		print_usage(cerr, string(*argv),	"\n"
											"--sequences FILE\n"
											"    --i_name ID --j_name ID\n"
								    		"    OR\n"
											"    --pairs \"INDICES\"\n"
											"[OPTIONS]\n"
											"< ALIGNMENT_DATA",
							all_args, exe_description, 80);
		return false;
	}
	check_required_options(vm, mandatory_args);

	// check pair indices
	try
	{
		parse_indices(pair_indices_str, args.pair_indices);
	}
	catch (std::runtime_error& err)
	{
		throw std::runtime_error(string("--pairs INDICES incorrectly specified:\n") +
											err.what());
	}

	if (vm.count("i_name") && !vm.count("j_name"))
		throw std::runtime_error("The option --j_name ID is missing.");
	if (vm.count("j_name") && !vm.count("i_name"))
		throw std::runtime_error("The option --i_name ID is missing.");
	args.open_err_log();
	return true;
}













